home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch9 / Planets.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1999-05-28  |  8.2 KB  |  272 lines

  1. VERSION 5.00
  2. Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
  3. Begin VB.Form PlanetForm 
  4.    BorderStyle     =   1  'Fixed Single
  5.    Caption         =   "Planets"
  6.    ClientHeight    =   5775
  7.    ClientLeft      =   1575
  8.    ClientTop       =   720
  9.    ClientWidth     =   6015
  10.    LinkTopic       =   "Form1"
  11.    MaxButton       =   0   'False
  12.    MinButton       =   0   'False
  13.    PaletteMode     =   1  'UseZOrder
  14.    ScaleHeight     =   385
  15.    ScaleMode       =   3  'Pixel
  16.    ScaleWidth      =   401
  17.    Begin VB.TextBox txtFramesPerSecond 
  18.       Height          =   285
  19.       Left            =   1560
  20.       TabIndex        =   3
  21.       Text            =   "20"
  22.       Top             =   5400
  23.       Width           =   375
  24.    End
  25.    Begin VB.CommandButton cmdRun 
  26.       Caption         =   "Run"
  27.       Default         =   -1  'True
  28.       Enabled         =   0   'False
  29.       Height          =   495
  30.       Left            =   2160
  31.       TabIndex        =   1
  32.       Top             =   5280
  33.       Width           =   855
  34.    End
  35.    Begin VB.PictureBox picCanvas 
  36.       AutoRedraw      =   -1  'True
  37.       FillStyle       =   0  'Solid
  38.       Height          =   5250
  39.       Left            =   0
  40.       ScaleHeight     =   346
  41.       ScaleMode       =   3  'Pixel
  42.       ScaleWidth      =   396
  43.       TabIndex        =   0
  44.       Top             =   0
  45.       Width           =   6000
  46.    End
  47.    Begin MSComDlg.CommonDialog dlgFile 
  48.       Left            =   3120
  49.       Top             =   5280
  50.       _ExtentX        =   847
  51.       _ExtentY        =   847
  52.       _Version        =   393216
  53.       CancelError     =   -1  'True
  54.    End
  55.    Begin VB.Label Label1 
  56.       Caption         =   "Frames per second:"
  57.       Height          =   255
  58.       Left            =   120
  59.       TabIndex        =   2
  60.       Top             =   5400
  61.       Width           =   1455
  62.    End
  63.    Begin VB.Menu mnuFile 
  64.       Caption         =   "&File"
  65.       Begin VB.Menu mnuFileOpen 
  66.          Caption         =   "&Open..."
  67.          Shortcut        =   ^O
  68.       End
  69.    End
  70. Attribute VB_Name = "PlanetForm"
  71. Attribute VB_GlobalNameSpace = False
  72. Attribute VB_Creatable = False
  73. Attribute VB_PredeclaredId = True
  74. Attribute VB_Exposed = False
  75. Option Explicit
  76. Private Playing As Boolean
  77. Private NumPlanets As Integer
  78. Private Cx() As Double          ' Position.
  79. Private Cy() As Double
  80. Private Vx() As Double          ' Velocity.
  81. Private Vy() As Double
  82. Private M() As Double           ' Mass.
  83. Private R() As Double           ' Radius.
  84. Private Clr() As Long           ' Colors.
  85. Private BitmapWid As Long
  86. Private BitmapHgt As Long
  87. Private BitmapNumBytes As Long
  88. Private Bytes() As Byte
  89. ' Draw some random rectangles on the bacground.
  90. Private Sub DrawBackground()
  91. Dim X As Single
  92. Dim Y As Single
  93. Dim xmax As Single
  94. Dim ymax As Single
  95. Dim i As Integer
  96.     ' Start with a clean slate.
  97.     picCanvas.Line (0, 0)-(picCanvas.ScaleWidth, picCanvas.ScaleHeight), vbBlack, BF
  98.     ' Draw some "stars."
  99.     xmax = picCanvas.ScaleWidth
  100.     ymax = picCanvas.ScaleHeight
  101.     For i = 1 To 100
  102.         X = Rnd * xmax
  103.         Y = Rnd * ymax
  104.         picCanvas.PSet (X, Y), vbWhite
  105.     Next i
  106.     ' Make the background permanent.
  107.     picCanvas.Picture = picCanvas.Image
  108. End Sub
  109. ' Load the data in a planet file.
  110. Private Sub LoadPlanets(file_name As String)
  111. Dim fnum As Integer
  112. Dim i As Integer
  113. Dim old_style As Integer
  114. Dim bm As BITMAP
  115.     ' Make a random background.
  116.     DrawBackground
  117.     ' Save the background bitmap data.
  118.     GetObject picCanvas.Image, Len(bm), bm
  119.     BitmapWid = bm.bmWidthBytes
  120.     BitmapHgt = bm.bmHeight
  121.     BitmapNumBytes = BitmapWid * BitmapHgt
  122.     ReDim Bytes(1 To bm.bmWidthBytes, 1 To bm.bmHeight)
  123.     GetBitmapBits picCanvas.Image, BitmapNumBytes, Bytes(1, 1)
  124.     ' Load the data.
  125.     fnum = FreeFile
  126.     Open file_name For Input As #fnum
  127.         
  128.     Input #fnum, NumPlanets
  129.     ReDim Cx(1 To NumPlanets)
  130.     ReDim Cy(1 To NumPlanets)
  131.     ReDim Vx(1 To NumPlanets)
  132.     ReDim Vy(1 To NumPlanets)
  133.     ReDim M(1 To NumPlanets)
  134.     ReDim R(1 To NumPlanets)
  135.     ReDim Clr(1 To NumPlanets)
  136.     For i = 1 To NumPlanets
  137.         Input #fnum, _
  138.             Cx(i), Cy(i), Vx(i), Vy(i), M(i), Clr(i)
  139.         R(i) = Sqr(M(i)) + 1
  140.     Next i
  141.         
  142.     Close #fnum
  143.     ' Draw the planets.
  144.     old_style = picCanvas.FillStyle
  145.     picCanvas.FillStyle = vbSolid
  146.     picCanvas.Cls
  147.     For i = 1 To NumPlanets
  148.         picCanvas.FillColor = Clr(i)
  149.         picCanvas.Circle (Cx(i), Cy(i)), R(i), Clr(i)
  150.     Next i
  151.     picCanvas.FillStyle = old_style
  152.     Caption = "Planets [" & file_name & "]"
  153.     cmdRun.Enabled = True
  154. End Sub
  155. ' Make the planets move until Playing is false.
  156. Private Sub RunSimulation()
  157. Dim ms_per_frame As Long
  158.     ' See how fast we should go.
  159.     If Not IsNumeric(txtFramesPerSecond.Text) Then _
  160.         txtFramesPerSecond.Text = "10"
  161.     ms_per_frame = 1000 \ CLng(txtFramesPerSecond.Text)
  162.     PlayImages ms_per_frame
  163. End Sub
  164. ' Make the planets move until Playing is false.
  165. Private Sub PlayImages(ByVal ms_per_frame As Long)
  166. Const F_SCALE = 1000
  167. Dim next_time As Long
  168. Dim i As Integer
  169. Dim j As Integer
  170. Dim dx As Double
  171. Dim dy As Double
  172. Dim d2 As Double
  173. Dim d As Double
  174. Dim f As Double
  175. Dim a_d As Double
  176.     ' Start the animation.
  177.     next_time = GetTickCount()
  178.     Do While Playing
  179.         ' Calculate the forces on the planets.
  180.         For i = 1 To NumPlanets - 1
  181.             For j = i + 1 To NumPlanets
  182.                 ' Calculate the force between planets
  183.                 ' i and j. Translate the force into a
  184.                 ' change in velocity.
  185.                 dx = Cx(i) - Cx(j)
  186.                 dy = Cy(i) - Cy(j)
  187.                 d2 = dx * dx + dy * dy
  188.                 f = F_SCALE * M(i) * M(j) / d2
  189.                 d = Sqr(d2)
  190.                             
  191.                 a_d = f / M(i) / d
  192.                 Vx(i) = Vx(i) - a_d * dx
  193.                 Vy(i) = Vy(i) - a_d * dy
  194.             
  195.                 a_d = f / M(j) / d
  196.                 Vx(j) = Vx(j) + a_d * dx
  197.                 Vy(j) = Vy(j) + a_d * dy
  198.             Next j
  199.         Next i
  200.         
  201.         ' Move all the planets.
  202.         For i = 1 To NumPlanets
  203.             Cx(i) = Cx(i) + Vx(i)
  204.             Cy(i) = Cy(i) + Vy(i)
  205.         Next i
  206.            
  207.         ' Restore the background.
  208.         SetBitmapBits picCanvas.Image, BitmapNumBytes, Bytes(1, 1)
  209.         ' Redraw the planets.
  210.         For i = 1 To NumPlanets
  211.             picCanvas.FillColor = Clr(i)
  212.             picCanvas.Circle (Cx(i), Cy(i)), R(i), Clr(i)
  213.         Next i
  214.         ' Wait until it's time for the next frame.
  215.         next_time = next_time + ms_per_frame
  216.         WaitTill next_time
  217.     Loop
  218. End Sub
  219. ' Start a new simulation.
  220. Private Sub cmdRun_Click()
  221.     If Playing Then
  222.         cmdRun.Caption = "Stopped"
  223.         cmdRun.Enabled = False
  224.         Playing = False
  225.     Else
  226.         Playing = True
  227.         cmdRun.Caption = "Stop"
  228.         RunSimulation
  229.         cmdRun.Caption = "Run"
  230.         cmdRun.Enabled = True
  231.         Playing = False
  232.     End If
  233. End Sub
  234. Private Sub Form_Load()
  235.     picCanvas.FillStyle = vbSolid
  236.     dlgFile.InitDir = App.Path
  237.     dlgFile.Filter = _
  238.         "Planet Files (*.pla)|*.pla|" & _
  239.         "All Files (*.*)|*.*"
  240. End Sub
  241. Private Sub Form_Resize()
  242. Const GAP = 3
  243. Dim hgt As Double
  244.     hgt = ScaleHeight - cmdRun.Height - 2 * GAP
  245.     picCanvas.Move 0, 0, ScaleWidth, hgt
  246.     cmdRun.Move (ScaleWidth - cmdRun.Width) / 2, _
  247.         picCanvas.Height + GAP
  248.     Label1.Top = cmdRun.Top
  249.     txtFramesPerSecond.Top = cmdRun.Top
  250. End Sub
  251. ' Load a new data file.
  252. Private Sub mnuFileOpen_Click()
  253. Dim fname As String
  254.     ' Allow the user to pick a file.
  255.     On Error Resume Next
  256.     dlgFile.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  257.     dlgFile.ShowOpen
  258.     If Err.Number = cdlCancel Then
  259.         Exit Sub
  260.     ElseIf Err.Number <> 0 Then
  261.         Beep
  262.         MsgBox "Error selecting file.", , vbExclamation
  263.         Exit Sub
  264.     End If
  265.     On Error GoTo 0
  266.     fname = Trim$(dlgFile.FileName)
  267.     dlgFile.InitDir = Left$(fname, Len(fname) _
  268.         - Len(dlgFile.FileTitle) - 1)
  269.     ' Load the data.
  270.     LoadPlanets fname
  271. End Sub
  272.